package tmt.usercenter.web.service;

import lombok.Getter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tmt.usercenter.web.bean.TmtSemaphore;
import tmt.usercenter.web.domain.RealNameMaterial;
import tmt.usercenter.web.domain.TmtUser;
import tmt.usercenter.web.domain.enums.AuditStatus;
import tmt.usercenter.web.domain.enums.IdCardType;
import tmt.usercenter.web.repository.IRealNameMaterialRepo;
import tmt.usercenter.web.repository.ITmtUserRepo;

import java.util.ArrayList;

@Service
@Transactional(rollbackFor = Exception.class)
public class RealNameMaterialService extends TmtBaseService<RealNameMaterial, Long> {

    @Getter
    private IRealNameMaterialRepo realNameMaterialRepo;

    private ITmtUserRepo userRepo;

    private SemaphoreService semaphoreService;

    @Autowired
    public RealNameMaterialService(IRealNameMaterialRepo realNameMaterialRepo,
                                   ITmtUserRepo userRepo,
                                   SemaphoreService semaphoreService) {
        super(realNameMaterialRepo, new ArrayList<>());
        this.realNameMaterialRepo = realNameMaterialRepo;
        this.userRepo = userRepo;
        this.semaphoreService = semaphoreService;
    }

    @Override
    public RealNameMaterial create(RealNameMaterial object) throws Exception {
        object = super.create(object);
        updateUserProperties(object);
        return object;
    }

    @Override
    public RealNameMaterial update(RealNameMaterial object) throws Exception {
        RealNameMaterial material = object;
        TmtSemaphore semaphore = semaphoreService.getSemaphore(RealNameMaterial.class, material.getId());
        semaphore.acquire();
        try {
            object = super.update(object);
            updateUserProperties(object);
        } finally {
            semaphore.release();
        }
        return object;
    }

    @Transactional(readOnly = true)
    public RealNameMaterial findFirstByUserIdOrderByIdDesc(Long userId) {
        return realNameMaterialRepo.findFirstByUserIdOrderByIdDesc(userId);
    }

    private void updateUserProperties(RealNameMaterial material) {
        TmtUser user = userRepo.findById(material.getUser().getId());
        if (material.getAuditStatus() == AuditStatus.AUDIT_SUCCESS
                && material.getCardType() == IdCardType.ID_CARD_2) {
            user.setCardType(IdCardType.ID_CARD_2);
            user.setIdCardNum(material.getCardNo());
            user.setRealName(material.getName());
            user.setRealNameChecked(true);
        } else {
            user.setRealNameChecked(false);
        }
        userRepo.save(user);
    }
}
